﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Common
{
    public static class ListHelper
    {
        // Methods
        public static string ObjListToXml<T>(List<T> enitities, string headtag)
        {
            StringBuilder builder = new StringBuilder();
            PropertyInfo[] properties = null;
            builder.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            builder.AppendLine("<" + headtag + ">");
            foreach (T local in enitities)
            {
                if (properties == null)
                {
                    properties = local.GetType().GetProperties();
                }
                builder.AppendLine("<item>");
                foreach (PropertyInfo info in properties)
                {
                    builder.Append("<");
                    builder.Append(info.Name);
                    builder.Append(">");
                    builder.Append(info.GetValue(local, null));
                    builder.Append("</");
                    builder.Append(info.Name);
                    builder.AppendLine(">");
                }
                builder.AppendLine("</item>");
            }
            builder.AppendLine("</" + headtag + ">");
            return builder.ToString();
        }

        public static DataSet ToDataSet<T>(this IList<T> list)
        {
            DataSet set = new DataSet();
            DataTable table = list.ToDataTable<T>();
            if (table != null)
            {
                set.Tables.Add(table);
            }
            return set;
        }

        public static DataTable ToDataTable<T>(this IList<T> list)
        {
            if ((list == null) || (list.Count <= 0))
            {
                return null;
            }
            DataTable table = new DataTable(typeof(T).Name);
            PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (T local in list)
            {
                if (local != null)
                {
                    DataRow row = table.NewRow();
                    int index = 0;
                    int length = properties.Length;
                    while (index < length)
                    {
                        PropertyInfo info = properties[index];
                        string name = info.Name;
                        if (table.Columns[name] == null)
                        {
                            DataColumn column = new DataColumn(name, info.PropertyType);
                            table.Columns.Add(column);
                        }
                        row[name] = info.GetValue(local, null);
                        index++;
                    }
                    table.Rows.Add(row);
                }
            }
            return table;
        }

        public static List<T> XmlToObjList<T>(string xml, string headtag) where T : new()
        {
            List<T> list = new List<T>();
            XmlDocument document = new XmlDocument();
            PropertyInfo[] properties = null;
            document.LoadXml(xml);
            XmlNodeList list2 = document.SelectNodes(headtag);
            if (list2 != null)
            {
                foreach (XmlNode node in list2)
                {
                    T local2 = default(T);
                    T local = (local2 == null) ? Activator.CreateInstance<T>() : default(T);
                    if (properties == null)
                    {
                        properties = local.GetType().GetProperties();
                    }
                    foreach (PropertyInfo info in properties)
                    {
                        XmlNode node2 = node.SelectSingleNode(info.Name);
                        if (node2 != null)
                        {
                            string innerXml = node2.InnerXml;
                            info.SetValue(local, Convert.ChangeType(innerXml, info.PropertyType), null);
                        }
                        else if ((node.FirstChild != null) && !node.FirstChild.HasChildNodes)
                        {
                            string innerText = node.InnerText;
                            info.SetValue(local, Convert.ChangeType(innerText, info.PropertyType), null);
                        }
                    }
                    list.Add(local);
                }
            }
            return list;
        }
    }
}
